using System.Linq.Expressions;

namespace Chaotic.DataBase.DBAccessLibrary.Model;

public static class FieldEntityEx
{
	public static bool IsChange<T, TProperty>(this T? entity, Expression<Func<T, TProperty>> func) where T : FieldEntity
	{
		if (func.Body is MemberExpression memberExpression)
		{
			string name = memberExpression.Member.Name;
			object value = entity.GetType().GetProperty(name).GetValue(entity, null);
			if (entity._changeDic.ContainsKey(name))
			{
				return value != entity._changeDic[name];
			}
		}
		return false;
	}

	public static bool IsChange<T>(this T entity, string protecName) where T : FieldEntity
	{
		if (!string.IsNullOrEmpty(protecName))
		{
			try
			{
				object value = entity.GetType().GetProperty(protecName).GetValue(entity, null);
				if (entity._changeDic.ContainsKey(protecName))
				{
					return value != entity._changeDic[protecName];
				}
			}
			catch
			{
			}
		}
		return false;
	}

	public static object GetNoChangeValue<T, TProperty>(this T? entity, Expression<Func<T, TProperty>> func) where T : FieldEntity
	{
		if (func.Body is MemberExpression memberExpression)
		{
			string name = memberExpression.Member.Name;
			if (entity._changeDic.ContainsKey(name))
			{
				return entity._changeDic[name];
			}
		}
		return null;
	}

	internal static void Change<T, TProperty>(this T entity, Expression<Func<T, TProperty>> func, object? newValue) where T : FieldEntity
	{
		if (!(func.Body is MemberExpression memberExpression) || !entity._isBackup)
		{
			return;
		}
		if (entity.Status == EditStatus.UnChange)
		{
			object value = entity.GetType().GetProperty(memberExpression.Member.Name).GetValue(entity, null);
			entity.Status = EditStatus.Modify;
			entity._changeDic.Add(memberExpression.Member.Name, value);
		}
		else if (entity._changeDic.ContainsKey(memberExpression.Member.Name))
		{
			if (newValue.Equals(entity._changeDic[memberExpression.Member.Name]))
			{
				entity._changeDic.Remove(memberExpression.Member.Name);
			}
			if (entity._changeDic.Count == 0)
			{
				entity.Status = EditStatus.UnChange;
			}
		}
		else
		{
			object value2 = entity.GetType().GetProperty(memberExpression.Member.Name).GetValue(entity, null);
			entity._changeDic.Add(memberExpression.Member.Name, value2);
		}
	}
}
